package com.kfm.wiki.service.impl;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.kfm.wiki.entity.Content;
import com.kfm.wiki.entity.Doc;
import com.kfm.wiki.ex.BussinessException;
import com.kfm.wiki.mapper.ContentMapper;
import com.kfm.wiki.mapper.DocMapper;
import com.kfm.wiki.service.DocService;
import com.kfm.wiki.socket.WebSocketService;
import com.kfm.wiki.util.Contains;
import com.kfm.wiki.util.IPUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
* @author 10854
* @description 针对表【doc(文档)】的数据库操作Service实现
* @createDate 2022-12-17 10:17:14
*/
@Service
public class DocServiceImpl extends ServiceImpl<DocMapper, Doc>
    implements DocService{

    @Autowired
    ContentMapper contentMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private WebSocketService webSocketService;

    @Override
    public PageInfo<Doc> list(Integer current, Integer pageSize, Doc doc) {
        PageHelper.startPage(current, pageSize);

        List<Doc> list = query(doc);

        return new PageInfo<>(list);
    }

    @Override
    public List<Tree<String>> all(Doc doc) {
        // 查询所有分类
        List<Doc> list = query(doc);
        // 树形数据
//        return tree(0L, list);
        List<Tree<String>> treeList = TreeUtil.build(list, "0", (treeNode, tree) -> {
            tree.setId(treeNode.getId().toString());
            tree.setParentId(treeNode.getParent().toString());
            tree.setName(treeNode.getName());
            // 扩展属性 ...
            tree.putExtra("parent", treeNode.getParent().toString());
            tree.putExtra("sort", treeNode.getSort());
            tree.putExtra("viewCount", treeNode.getViewCount());
            tree.putExtra("voteCount", treeNode.getVoteCount());
            tree.putExtra("content", treeNode.getContent());
        });

        return treeList;
    }

    /**
     * 数据库查询
     根据条件查询数据库
     * @param doc
     * @return
     */
    private List<Doc> query(Doc doc){
        List<Doc> docs = getBaseMapper().selectList(doc);
        return docs;
    }



    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(Doc doc) {
        Content content = new Content();
        if (ObjectUtils.isEmpty(doc.getId())){
            // 新增分类
            // 设置 id
            long id = IdUtil.getSnowflakeNextId();
            doc.setId(id);
            // 保存文档
            getBaseMapper().insert(doc);
            // 文档内容
            content.setId(id);
            content.setContent(doc.getContent());
            return contentMapper.insert(content) > 0;
        } else{
            // 编辑信息
            getBaseMapper().updateById(doc);
            content.setId(doc.getId());
            content.setContent(doc.getContent());
            return contentMapper.updateById(content) > 0;
        }

    }

    @Override
    public boolean deleteCascade(Long id) {
        UpdateWrapper<Doc> updateWrapper = new UpdateWrapper<>();

        updateWrapper.eq("id", id);
        updateWrapper.or(true);
        updateWrapper.eq("parent", id);

        return getBaseMapper().delete(updateWrapper) > 0;
    }

    @Override
    public int incrementVote(Long id) {
        // 判断一个人(ip)一天 只能对一个文章点赞一次
        String ip = IPUtil.getRemoteAddr();
        if (redisTemplate.hasKey(Contains.REDIS_VOTE_KEY_PRE + ip + "_" + id)) {
            throw new BussinessException("您今天已对此文档点赞过了");
        } else{
            redisTemplate.opsForValue().set(Contains.REDIS_VOTE_KEY_PRE + ip + "_" + id, 1, 24, TimeUnit.HOURS);
            // 修改数据库记录
            int row = getBaseMapper().incrementVoteCount(id);

            Doc doc = getBaseMapper().selectById(id);
            // 发送点赞通知
            webSocketService.sendMsg("【 " + doc.getName() + " 】 被点赞了");
            return row;
        }
    }


}




